Skip to content

Add asyncio support to the Python SDK - #57

Merged
kvz merged 66 commits into
py310-v2from
asyncio-v2
Oct 11, 2026
Merged

kvz merged 66 commits into
py310-v2from
asyncio-v2

Conversation

@kvz

@kvz kvz commented May 20, 2026 •

Copy link
Copy Markdown
Member

Why

Python SDK 2.0 adds asyncio over the existing handwritten client surface, together with the Python 3.12+ floor and version preparation in #56. AsyncTransloadit mirrors the synchronous Assembly, Template and billing methods and shares Smart CDN signing.

Closes #9.

Changes

  • Added async clients/helpers with aiohttp session ownership, completion polling via asyncio.sleep, and tuspy resumable uploads in worker threads. Cancellation drains active file reads/uploads before caller-owned files close.
  • Preserved handwritten sync/async methods, request signing, custom services and proxy/TLS configuration. Canonical response fields are used in examples/tests: Assembly assembly_id, assembly_ssl_url, assembly_url; Template id, name, content.
  • Polling retry exhaustion raises AssemblyPollingError, retaining the Assembly URL and creation/last responses for recovery. Error/response serialization preserves those values. Unsigned query value encoding and empty/whitespace responses match sync behavior while JSON null remains distinct.
  • CHANGELOG 2.0.0 covers asyncio, Python 3.12+ and upgrade notes. README/Sphinx explain request corrections and that tuspy transfers do not inherit injected aiohttp session settings.

Contract-generated endpoints are outside 2.0. Removed the Python-local generator, contract pin, generated blocks/transports, coverage table and CI/tox drift checks. #61 preserves the complete pre-removal snapshot and links #60; it waits for API2-owned SDK emitters in api2#9252, owned by the existing studio1 ~/code/api2 session.

Validation and council review

  • Final Docker matrix on 3c0a3a3: 167 passed, 12 opt-in skips on each Python 3.12/3.13/3.14; 94.22% coverage and Node CLI signature parity pass.
  • All 24 live upload, Template lifecycle and runnable-example checks pass.
  • Poetry metadata, strict Sphinx, wheel/sdist build/scope checks, release-helper dry run, shell syntax and diff checks pass. The public sync/async surface matches the original handwritten client.
  • Final CI 38162453747: all seven jobs green, including Windows 3.12/3.13/3.14 and live E2E.
  • Three narrowed council rounds used Claude Opus and Codex Astra plus arbitration. Round 1 fixed explicit polling exhaustion, query/empty-response parity and migration/session/toolchain documentation. Round 2 preserved recovery details and complete query value formats; additional fail-first checks repaired response/error pickle behavior. Canonical-field, polling, query and serialization regressions were observed failing before fixes. Round 3 returned No issues found. Its raw optional wire-escaping suggestion concerns equivalent decoded unsigned query values; the response module is already included in Sphinx autodoc.

Release

Released on 2026-10-11 after the approved squash sequence #57 → #56 → main. The release commit and v2.0.0 tag are 46a98f3bf48762839b7f14a378beb359d74c0a8e.

  • GitHub release and PyPI 2.0.0 are published. Both uploaded artifacts match local SHA-256 hashes. A clean Python 3.12 install from PyPI passed sync/async surface, session/factory and polling-recovery serialization checks.
  • Release-commit CI passed all seven jobs, including Windows 3.12/3.13/3.14 and live E2E.
  • Read the Docs built the release commit successfully for both latest and stable; the served docs include 2.0.0, asyncio and the Python 3.12+ floor.
  • The required Dependabot check fell from 64 to 29 open alerts; one critical development-only anyio alert remains, with an automated update PR already open. The fresh PyPI install resolved patched runtime dependencies (aiohttp 3.14.5, urllib3 2.8.0). Existing dependency follow-ups remain outside this release-scope change.

tim-kos remains requested; both cards are Done. Contract generation remains deferred in #61, blocked by api2#9252 and linked to #60.

Friction: review caught recovery/query gaps after the first fixes, requiring two further CI batches. Review sandboxes restricted some local networking/capture, so full local Docker/live checks and actual seven-job CI provide runtime evidence. The release has no remaining council findings.

🤖 Claimed by kvz on framework1/python-sdk since 2026-10-11 · resume: codex resume 01a12c04-6ff8-7a91-9987-654db44d852e

@kvz kvz self-assigned this May 20, 2026
@codecov-commenter

codecov-commenter commented May 20, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.48872% with 36 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.71%. Comparing base (2397ea5) to head (3c0a3a3).

Files with missing lines Patch % Lines
transloadit/assembly.py 88.65% 11 Missing ⚠️
transloadit/async_request.py 95.81% 9 Missing ⚠️
transloadit/async_client.py 95.12% 4 Missing ⚠️
transloadit/client.py 91.48% 4 Missing ⚠️
transloadit/api_url.py 94.11% 2 Missing ⚠️
transloadit/request.py 93.54% 2 Missing ⚠️
transloadit/upload.py 93.10% 2 Missing ⚠️
transloadit/async_template.py 94.11% 1 Missing ⚠️
transloadit/template.py 87.50% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##           py310-v2      #57      +/-   ##
============================================
+ Coverage     86.60%   95.71%   +9.10%     
============================================
  Files             7       15       +8     
  Lines           209      933     +724     
  Branches         19      130     +111     
============================================
+ Hits            181      893     +712     
- Misses           28       40      +12     
Flag Coverage Δ
unittests 95.71% <95.48%> (+9.10%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@kvz

kvz commented May 21, 2026

Copy link
Copy Markdown
Member Author

Setting this back to draft while we expand the feature scope: the v2 PR should also cover the full Transloadit API endpoint surface before we treat it as ready. I added a matching @todo to the 2.0.0 CHANGELOG section so the release notes get updated once the endpoint coverage is complete.

@kvz
kvz marked this pull request as draft May 21, 2026 14:07
kvz and others added 11 commits June 10, 2026 13:22
The generator no longer emits function-local imports; base64, urljoin,
and requests (sync only) now live in the handwritten module headers
where Python convention expects them.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
resume_tus_upload() is generated from the API2 resumeUpload TUS protocol
contract in both the sync and asyncio clients: it discovers the server
offset with a HEAD request, PATCHes the remaining bytes from that offset,
asserts the final offset matches the content length, and waits for the
Assembly to finish. The new api2-devdock-tus-resume-upload example
interrupts an upload after the first chunk like a dropped connection
would, then resumes it through the public SDK method.

The lifecycle example now polls the Assembly list briefly because the API
acknowledges creation before the list storage row lands.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
# Conflicts:
#	.github/workflows/ci.yml
@kvz
kvz marked this pull request as ready for review October 10, 2026 22:14
@kvz
kvz requested a review from tim-kos October 10, 2026 22:15
@kvz
kvz merged commit eecb1cc into py310-v2 Oct 11, 2026
7 checks passed
@kvz
kvz deleted the asyncio-v2 branch October 11, 2026 18:13
@kvz kvz mentioned this pull request Oct 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants